package com.lgl.mes.common.util.org.easy.excel.aop.cell.inner;

import com.lgl.mes.common.util.org.easy.excel.aop.cell.CellInterceptor;
import com.lgl.mes.common.util.org.easy.excel.aop.cell.CellInterceptorAdapter;
import com.lgl.mes.common.util.org.easy.excel.aop.cell.CellJoinPoint;
import com.lgl.mes.common.util.org.easy.excel.exception.ExcelException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.util.ClassUtils;
import org.springframework.util.ConcurrentReferenceHashMap;

import java.util.Map;

/**
 * 处理cellInterceptor标签
 * @author lisuo
 *
 */
public class CustomCellInterceptor extends CellInterceptorAdapter {

	private Map<String, CellInterceptor> cellInterceptors = new ConcurrentReferenceHashMap<>();

	@Override
	public boolean supports(CellJoinPoint joinPoint) {
		return joinPoint.getFieldValue().getCellInterceptor() != null;
	}

	@Override
	public Object executeImport(CellJoinPoint joinPoint) throws ExcelException {
		CellInterceptor interceptor = getCellInterceptor(joinPoint.getFieldValue().getCellInterceptor(),
				joinPoint.getCtx());
		if (interceptor.supports(joinPoint)) {
			return interceptor.executeImport(joinPoint);
		}
		return super.executeImport(joinPoint);
	}

	@Override
	public Object executeExport(CellJoinPoint joinPoint) throws ExcelException {
		CellInterceptor interceptor = getCellInterceptor(joinPoint.getFieldValue().getCellInterceptor(),
				joinPoint.getCtx());
		if (interceptor.supports(joinPoint)) {
			return interceptor.executeExport(joinPoint);
		}
		return super.executeExport(joinPoint);
	}

	private CellInterceptor getCellInterceptor(String clazz, ApplicationContext ctx) {
		try {
			CellInterceptor bean = cellInterceptors.get(clazz);
			if (bean == null) {
				if (ctx != null) {
					try {
						bean = (CellInterceptor) ctx.getBean(Class.forName(clazz));
					} catch (NoSuchBeanDefinitionException ignore) {}
				} 
				if(bean == null) {
					bean = (CellInterceptor) BeanUtils.instantiateClass(ClassUtils.forName(clazz, null));
				}
				cellInterceptors.put(clazz, bean);
			}
			return bean;
		} catch (BeansException e) {
			throw e;
		} catch (Exception e) {
			throw new ExcelException(e);
		}
	}

}
